home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / animals.c next >
C/C++ Source or Header  |  1990-07-23  |  6KB  |  306 lines

  1. /*  animals - guessing game    Authors: Terrence W. Holm & Edwin L. Froese */
  2.  
  3. #include <sys/types.h>
  4. #include <string.h>
  5. #include <signal.h>
  6. #include <sgtty.h>
  7. #include <ctype.h>
  8. #include <unistd.h>
  9. #include <stdio.h>
  10.  
  11. #define  ANIMALS    "/usr/lib/animals"
  12. #define  DEFAULT_ANIMAL    "beaver"
  13. #define  MAX_NODES    999    /* Enough for 500 animals  */
  14. #define  MAX_LINE    90
  15.  
  16. void Abort();
  17. char *Get_Animal();
  18. char *Get_Question();
  19. char *A_or_An();
  20. char *Alloc();
  21.  
  22. struct node {
  23.   int question;
  24.   char *text;
  25.   int yes;
  26.   int no;
  27. } animals[MAX_NODES];
  28.  
  29. int count = 0;
  30. struct sgttyb old_tty_mode;
  31.  
  32.  
  33. main(argc, argv)
  34. int argc;
  35. char *argv[];
  36.  
  37. {
  38.   char *animal_file = ANIMALS;
  39.  
  40.   if (argc > 2) {
  41.     fprintf(stderr, "Usage:  %s  [ data_base ]\n", argv[0]);
  42.     exit(1);
  43.   }
  44.   if (argc == 2) animal_file = argv[1];
  45.  
  46.   ioctl(0, TIOCGETP, &old_tty_mode);
  47.  
  48.   signal(SIGINT, Abort);
  49.   signal(SIGQUIT, Abort);
  50.  
  51.   if (access(animal_file, R_OK) == 0)
  52.     Read_Animals(animal_file);
  53.   else {
  54.     animals[0].question = 0;
  55.     animals[0].text = DEFAULT_ANIMAL;
  56.     count = 1;
  57.   }
  58.  
  59.   while (Ask("\nAre you thinking of an animal?")) {
  60.     int i = 0;
  61.  
  62.     while (1) {
  63.         if (animals[i].question) {
  64.             if (Ask(animals[i].text))
  65.                 i = animals[i].yes;
  66.             else
  67.                 i = animals[i].no;
  68.         } else {
  69.             printf("Were you thinking of %s %s",
  70.              A_or_An(animals[i].text), animals[i].text);
  71.  
  72.             if (Ask("?")) printf("I knew it!\n");
  73.  
  74.             else {
  75.                 /* Insert a new question and animal name  */
  76.  
  77.                 if (count + 2 > MAX_NODES)
  78.                     Error("Too many animal names");
  79.  
  80.                 animals[count].question = 0;
  81.                 animals[count].text = animals[i].text;
  82.                 ++count;
  83.  
  84.                 animals[count].question = 0;
  85.                 printf("What animal were you thinking of? ");
  86.                 animals[count].text = Get_Animal();
  87.                 ++count;
  88.  
  89.                 animals[i].question = 1;
  90.                 printf("What question would distinguish %s %s from\n%s %s? ",
  91.                        A_or_An(animals[count - 2].text), animals[count - 2].text,
  92.                        A_or_An(animals[count - 1].text), animals[count - 1].text);
  93.  
  94.                 animals[i].text = Get_Question();
  95.  
  96.                 printf("For %s %s, the answer would be",
  97.                        A_or_An(animals[count - 1].text), animals[count - 1].text);
  98.  
  99.                 if (Ask("?")) {
  100.                     animals[i].yes = count - 1;
  101.                     animals[i].no = count - 2;
  102.                 } else {
  103.                     animals[i].yes = count - 2;
  104.                     animals[i].no = count - 1;
  105.                 }
  106.             }
  107.  
  108.             break;
  109.         }
  110.     }            /* End while ( 1 )  */
  111.  
  112.   }
  113.  
  114.  
  115.   ioctl(0, TIOCSETP, &old_tty_mode);
  116.  
  117.   printf("\nThank you for playing \"animals\".\n");
  118.   printf("The animal data base is now being updated.\n");
  119.  
  120.   Write_Animals(animal_file);
  121.  
  122.   sleep(1);
  123.   printf("\nBye.\n");
  124.  
  125.   exit(0);
  126. }
  127.  
  128.  
  129. /*  Reading and writing the animal data base */
  130.  
  131.  
  132. Read_Animals(animal_file)
  133. char *animal_file;
  134.  
  135. {
  136.   FILE *f;
  137.   char buffer[MAX_LINE];
  138.  
  139.   if ((f = fopen(animal_file, "r")) == NULL)
  140.     Error("Can not open animal data base");
  141.  
  142.   while (fgets(buffer, MAX_LINE, f) != NULL) {
  143.     int string_length;
  144.     char *string;
  145.  
  146.     buffer[strlen(buffer) - 1] = '\0';
  147.  
  148.     swab(buffer, buffer, strlen(buffer));
  149.  
  150.     if (buffer[0] == 'q') {
  151.         char *end = strchr(buffer, '?');
  152.         string_length = end - buffer;
  153.         animals[count].question = 1;
  154.         sscanf(end+1, "%d:%d",&animals[count].yes,&animals[count].no);
  155.     } else {
  156.         animals[count].question = 0;
  157.         string_length = strlen(buffer) - 1;
  158.     }
  159.  
  160.     string = Alloc(string_length + 1);
  161.  
  162.     string[0] = '\0';
  163.     strncat(string, buffer + 1, string_length);
  164.  
  165.     animals[count].text = string;
  166.  
  167.     count++;
  168.   }
  169.  
  170.   fclose(f);
  171. }
  172.  
  173.  
  174. Write_Animals(animal_file)
  175. char *animal_file;
  176.  
  177. {
  178.   FILE *f;
  179.   int i;
  180.   char buffer[MAX_LINE];
  181.  
  182.   if ((f = fopen(animal_file, "w")) == NULL)
  183.     Error("Can not write animal data base");
  184.  
  185.   for (i = 0; i < count; ++i) {
  186.     if (animals[i].question) sprintf(buffer, "q%s%d:%d", animals[i].text,
  187.             animals[i].yes, animals[i].no);
  188.     else
  189.         sprintf(buffer, "a%s", animals[i].text);
  190.  
  191.     /* Make the data base a bit difficult to read  */
  192.     swab(buffer, buffer, strlen(buffer));
  193.     fprintf(f, "%s\n", buffer);
  194.   }
  195.  
  196.   fclose(f);
  197.   chmod(animal_file, 0666);
  198. }
  199.  
  200.  
  201. /*  Reading data from the user */
  202. int Ask(question)
  203. char *question;
  204. {
  205.   struct sgttyb new_tty_mode;
  206.   int response;
  207.  
  208.   new_tty_mode = old_tty_mode;
  209.   new_tty_mode.sg_flags |= CBREAK;
  210.   ioctl(0, TIOCSETP, &new_tty_mode);
  211.  
  212.   printf("%s ", question);
  213.  
  214.   while ((response = getchar()) != 'y' && response != 'n')
  215.     printf("\n%s [yn]?", question);
  216.   putchar('\n');
  217.   ioctl(0, TIOCSETP, &old_tty_mode);
  218.   if (response == 'y')
  219.     return(1);
  220.   else
  221.     return(0);
  222. }
  223.  
  224.  
  225. char *Get_Animal()
  226. {
  227.   char s[MAX_LINE];
  228.   char *text;
  229.   int text_length;
  230.  
  231.   fgets(s, MAX_LINE, stdin);
  232.   text_length = strlen(s);
  233.   text = Alloc(text_length);
  234.   text[0] = '\0';
  235.   strncat(text, s, text_length - 1);
  236.   return(text);
  237. }
  238.  
  239.  
  240. char *Get_Question()
  241. {
  242.   char s[MAX_LINE];
  243.   char *end;
  244.   char *text;
  245.  
  246.   fgets(s, MAX_LINE, stdin);
  247.  
  248.   /* Capitalize the first letter  */
  249.   if (islower(s[0])) s[0] = toupper(s[0]);
  250.  
  251.   /* Make sure the question ends with a '?'  */
  252.   if ((end = strchr(s, '?')) == NULL)
  253.     s[strlen(s) - 1] = '?';
  254.   else
  255.     end[1] = '\0';
  256.  
  257.   text = Alloc(strlen(s) + 1);
  258.   strcpy(text, s);
  259.   return(text);
  260. }
  261.  
  262.  
  263. /*  Utility routines */
  264. char *A_or_An(word)
  265. char *word;
  266. {
  267.   if (strchr("aeiouAEIOU", word[0]) == NULL)
  268.     return("a");
  269.   else
  270.     return("an");
  271. }
  272.  
  273.  
  274. char *Alloc(size)
  275. int size;
  276. {
  277.   char *malloc();
  278.   char *memory;
  279.  
  280.   if ((memory = malloc(size)) == NULL)
  281.     Error("No room in memory for all the animals");
  282.  
  283.   return(memory);
  284. }
  285.  
  286.  
  287. void Abort()
  288. {
  289.   ioctl(0, TIOCSETP, &old_tty_mode);
  290.  
  291.   printf("\nThank you for playing \"animals\".\n");
  292.   printf("Since you aborted, the animal data base will not be updated.\n");
  293.   sleep(1);
  294.   printf("\nBye.\n");
  295.   exit(1);
  296. }
  297.  
  298.  
  299. Error(message)
  300. char *message;
  301. {
  302.   ioctl(0, TIOCSETP, &old_tty_mode);
  303.   fprintf(stderr, "Error: %s\n", message);
  304.   exit(1);
  305. }
  306.